//
// Created by wkm on 2024-03-17.
//

#include "ScheduleKey.h"
#include <cstdio>

//密钥编排，16字节--->44列32bit密钥生成--> 11组16字节:分别用于11轮 轮密钥加运算
void ScheduleKey(unsigned char *inkey, unsigned char *outkey, int Nk, int Nr) {
    //inkey:初始16字节密钥key
    //outkey：11组*16字节扩展密钥expansionkey
    //Nk：4列
    //Nr：10轮round
    unsigned char temp[4], t;
    int x, i;
    /*copy the key*/
    //第0组：[0-3]直接拷贝
    for (i = 0; i < (4 * Nk); i++) {
        outkey[i] = inkey[i];
    }
    //第1-10组：[4-43]
    i = Nk;
    while (i < (4 * (Nr + 1))) //i=4~43 WORD 32bit的首字节地址，每一个4字节
    {//1次循环生成1个字节扩展密钥，4次循环生成一个WORD
        //temp：4字节数组：代表一个WORD密钥
        //i不是4的倍数的时候
        //每个temp = 每个outkey32bit = 4字节
        for (x = 0; x < 4; x++) {
            temp[x] = outkey[(4 * (i - 1)) + x];    //i：32bit的首字节地址
        }
//        printf("abcd:%x,%x,%x,%x\n", temp[0], temp[1], temp[2], temp[3]);
        //i是4的倍数的时候
        if (i % Nk == 0) {
            /*字循环：循环左移1字节 RotWord()*/
            t = temp[0];
            temp[0] = temp[1];
            temp[1] = temp[2];
            temp[2] = temp[3];
            temp[3] = t;
//            printf("abcd:%x,%x,%x,%x\n", temp[0], temp[1], temp[2], temp[3]);
            /*字节代换：SubWord()*/
            for (x = 0; x < 4; x++) {
                temp[x] = sbox[temp[x]];
            }
//            printf("abcd:%x,%x,%x,%x\n", temp[0], temp[1], temp[2], temp[3]);
            /*轮常量异或：Rcon[j]*/
            temp[0] ^= Rcon[(i / Nk) - 1];
//            printf("abcd:%x,%x,%x,%x\n", temp[0], temp[1], temp[2], temp[3]);
        }
        for (x = 0; x < 4; x++) {
            outkey[(4 * i) + x] = outkey[(4 * (i - Nk)) + x] ^ temp[x];
        }
        ++i;
    }
}
